package com.chatplus.application.service.draw.impl;

import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chatplus.application.common.logging.SouthernQuietLogger;
import com.chatplus.application.common.logging.SouthernQuietLoggerFactory;
import com.chatplus.application.common.page.PageParam;
import com.chatplus.application.dao.draw.MjJobDao;
import com.chatplus.application.domain.entity.draw.MjJobEntity;
import com.chatplus.application.domain.notification.SaveImageNotification;
import com.chatplus.application.domain.request.MjCallbackNotifyRequest;
import com.chatplus.application.enumeration.AiPlatformEnum;
import com.chatplus.application.enumeration.MjJobStatusEnum;
import com.chatplus.application.service.account.UserProductLogService;
import com.chatplus.application.service.draw.MjJobService;
import com.chatplus.application.util.ConfigUtil;
import com.chatplus.application.web.notification.NotificationPublisher;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

/**
 * MidJourney 任务表业务逻辑实现
 *
 * <p>Table: t_mj_job - MidJourney 任务表</p>
 *
 * @author developer
 * @see MjJobEntity
 */
@Service
public class MjJobServiceImpl extends ServiceImpl<MjJobDao, MjJobEntity> implements MjJobService {
    private static final SouthernQuietLogger LOGGER = SouthernQuietLoggerFactory.getLogger(MjJobServiceImpl.class);
    private final UserProductLogService userProductLogService;
    private final NotificationPublisher notificationPublisher;

    public MjJobServiceImpl(UserProductLogService userProductLogService,
                            NotificationPublisher notificationPublisher) {
        this.userProductLogService = userProductLogService;
        this.notificationPublisher = notificationPublisher;
    }

    @Override
    public MjJobEntity getByTaskId(String taskId) {
        return baseMapper.selectOne(new LambdaQueryWrapper<MjJobEntity>()
                .eq(MjJobEntity::getTaskId, taskId)
                .last("limit 1"));
    }

    @Override
    public Page<MjJobEntity> getMjJobPage(PageParam pageParam, Boolean finish, Long userId, Boolean publish) {
        LambdaQueryWrapper<MjJobEntity> wrapper = new LambdaQueryWrapper<MjJobEntity>()
                .eq(userId != null, MjJobEntity::getUserId, userId)
                .eq(publish != null, MjJobEntity::getPublish, Boolean.TRUE.equals(publish) ? 1 : 0)
                .orderByDesc(MjJobEntity::getCreatedAt);
        if (finish != null) {
            if (Boolean.TRUE.equals(finish)) {
                wrapper.eq(MjJobEntity::getProgress, 100);
                wrapper.eq(MjJobEntity::getStatus, MjJobStatusEnum.SUCCESS);
                wrapper.isNotNull(MjJobEntity::getImgUrl);
            } else {
                wrapper.ne(MjJobEntity::getProgress, -1);
                wrapper.lt(MjJobEntity::getProgress, 100);
            }
        }
        if (pageParam.getSize() == 0) {
            return baseMapper.selectPage(pageParam.toPage(), wrapper);
        }
        // 失败的任务直接删除
        return baseMapper.selectPage(pageParam.toPage(), wrapper);
    }

    @Override
    public long getRunningJobCount(Long userId) {
        return baseMapper.selectCount(new LambdaQueryWrapper<MjJobEntity>()
                .eq(MjJobEntity::getUserId, userId)
                .ne(MjJobEntity::getProgress, -1)
                .lt(MjJobEntity::getProgress, 100));
    }

    @Override
    public void handleNotify(MjJobEntity mjJobEntity, MjCallbackNotifyRequest request) {
        try {
            MjJobStatusEnum status = request.getStatus();
            mjJobEntity.setErrMsg(request.getFailReason());
            mjJobEntity.setStatus(status);
            mjJobEntity.setAction(request.getAction());
            if (StringUtils.isNotEmpty(request.getId())) {
                mjJobEntity.setTaskId(request.getId());
            }
            String progress = request.getProgress();
            String imageUrl = request.getImageUrl();
            if (StringUtils.isNotEmpty(imageUrl)) {
                mjJobEntity.setOrgMjUrl(imageUrl);
                if (imageUrl.startsWith("https://cdn.discordapp.com")) {
                    imageUrl = imageUrl.replaceFirst("https://cdn.discordapp.com", "https://discord.renrenai.online");
                }
                mjJobEntity.setImgUrl(imageUrl);
            }
            if (StringUtils.isNotEmpty(progress)) {
                progress = progress.replace("%", "");
                int progressInt = mjJobEntity.getProgress();
                if (NumberUtil.isInteger(progress)) {
                    progressInt = Integer.parseInt(progress);
                }
                mjJobEntity.setProgress(progressInt);
                if (progressInt == 100 && status == MjJobStatusEnum.SUCCESS && StringUtils.isNotEmpty(request.getImageUrl())) {
                    mjJobEntity.setImgUrl(imageUrl);
                    mjJobEntity.setButtons(request.getButtons());
                    mjJobEntity.setHash(request.getProperties().getMessageHash());
                    //发通知保存图片
                    SaveImageNotification notification = new SaveImageNotification();
                    notification.setBizType(AiPlatformEnum.MJ);
                    notification.setBizId(mjJobEntity.getId());
                    notification.setNetImgUrl(imageUrl);
                    notificationPublisher.publish(notification);
                }
            }
            if (status == MjJobStatusEnum.FAILURE) {
                mjJobEntity.setProgress(-1);
                mjJobEntity.setErrMsg(request.getFailReason());
                userProductLogService.refundProductToUser(mjJobEntity.getUserId(), ConfigUtil.getImagePower(mjJobEntity.getUserId(), AiPlatformEnum.MJ), AiPlatformEnum.MJ, null);
            }
            this.updateById(mjJobEntity);
        } catch (Exception e) {
            LOGGER.message("回调通知异常").exception(e).error();
        }
    }
}
